home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / V2 / DJTST200.ZIP / tests / libclink / check.cc next >
Encoding:
C/C++ Source or Header  |  1995-06-13  |  9.1 KB  |  351 lines

  1. /*
  2. **   Usage:   nm -g ../../lib/libc.a | check
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <ctype.h>
  9.  
  10. #include "slist.h"
  11. #include "objs.h"
  12.  
  13. //-----------------------------------------------------------------------------
  14.  
  15. char *predefs[] = { "main", "edata", "end", "etext", "environ", 0 };
  16.  
  17. char *ansi_fns[] = { "abort", "abs", "acos", "asctime", "asin",
  18. "atan", "atan2", "atexit", "atof", "atoi", "atol", "bsearch",
  19. "calloc", "ceil", "clearerr", "clock", "cos", "cosh", "ctime",
  20. "difftime", "div", "errno", "exit", "exp", "fabs", "fclose", "feof",
  21. "ferror", "fflush", "fgetc", "fgetpos", "fgets", "floor", "fmod",
  22. "fopen", "fprintf", "fputc", "fputs", "fread", "free", "freopen",
  23. "frexp", "fscanf", "fseek", "fsetpos", "ftell", "fwrite", "getc",
  24. "getchar", "getenv", "gets", "gmtime", "isalnum", "isalpha",
  25. "iscntrl", "isdigit", "isgraph", "islower", "isprint", "ispunct",
  26. "isspace", "isupper", "isxdigit", "labs", "ldexp", "ldiv",
  27. "localeconv", "localtime", "log", "log10", "longjmp", "main",
  28. "malloc", "mblen", "mbstowcs", "mbtowc", "memchr", "memcmp", "memcpy",
  29. "memmove", "memset", "mktime", "modf", "perror", "pow", "printf",
  30. "putc", "putchar", "puts", "qsort", "raise", "rand", "realloc",
  31. "remove", "rename", "rewind", "scanf", "setbuf", "setjmp",
  32. "setlocale", "setvbuf", "signal", "sin", "sinh", "sprintf", "sqrt",
  33. "srand", "sscanf", "strcat", "strchr", "strcmp", "strcoll", "strcpy",
  34. "strcspn", "strerror", "strftime", "strlen", "strncat", "strncmp",
  35. "strncpy", "strpbrk", "strrchr", "strspn", "strstr", "strtod",
  36. "strtok", "strtol", "strtoul", "strxfrm", "system", "tan", "tanh",
  37. "time", "tmpfile", "tmpnam", "tolower", "toupper", "ungetc",
  38. "wcstombs", "vfprintf", "vprintf", "vsprintf", "wcstombs", "wctomb", 0
  39. };
  40.  
  41. char *posix_fns[] = {
  42. "_exit", "access", "alarm", "cfgetispeed", "cfgetospeed", "cfsetispeed",
  43. "cfsetospeed", "chdir", "chmod", "chown", "close", "closedir", "confstr",
  44. "creat", "ctermid", "dup", "dup2", "execl", "execle", "execlp", "execv",
  45. "execve", "execvp", "fcntl", "fdopen", "fileno", "fnmatch", "fnmatch",
  46. "fork", "fpathconf", "fpathconf", "fstat", "getcwd", "getegid", "geteuid",
  47. "getgid", "getgrgid", "getgrnam", "getgroups", "getlogin", "getopt",
  48. "getpgrp", "getpid", "getppid", "getpwnam", "getpwuid", "getuid", "glob",
  49. "glob", "globfree", "globfree", "isatty", "kill", "link", "lseek", "mkdir",
  50. "mkfifo", "open", "opendir", "optarg", "opterr", "optind", "optopt",
  51. "pathconf", "pathconf", "pause", "pclose", "pipe", "popen", "read",
  52. "readdir", "regcomp", "regerror", "regexec", "regfree", "rewinddir",
  53. "rmdir", "setgid", "setpgid", "setsid", "setuid", "sigaction", "sigaddset",
  54. "sigdelset", "sigemptyset", "sigfillset", "sigismember", "siglongjmp",
  55. "sigpending", "sigprocmask", "sigsetjmp", "sigsuspend", "sleep", "stat",
  56. "sysconf", "sysconf", "tcdrain", "tcflow", "tcflush", "tcgetattr",
  57. "tcgetpgrp", "tcsendbreak", "tcsetattr", "tcsetpgrp", "times", "ttyname",
  58. "tzname", "tzset", "umask", "uname", "unlink", "utime", "wait", "waitpid",
  59. "wordexp", "wordfree", "write",
  60. 0 };
  61.  
  62. #define Tansi    0x01
  63. #define Tposix    0x02
  64. #define Tallow    0x04
  65. #define Tother    0x08
  66. #define Tstub    0x10
  67.  
  68. int name2type(char *c)
  69. {
  70.   int i;
  71.   if (c[0] == '_')
  72.     return Tallow;
  73.   for (i=0; ansi_fns[i]; i++)
  74.     if (strcmp(ansi_fns[i], c) == 0)
  75.       return Tansi;
  76.   for (i=0; posix_fns[i]; i++)
  77.     if (strcmp(posix_fns[i], c) == 0)
  78.       return Tposix;
  79.   if (c[0] == '_' && c[1] == '_')
  80.     for (i=0; posix_fns[i]; i++)
  81.       if (strcmp(posix_fns[i], c+2) == 0)
  82.     return Tposix;
  83.   for (i=0; predefs[i]; i++)
  84.     if (strcmp(predefs[i], c) == 0)
  85.       return Tallow;
  86.   return Tother;
  87. }
  88.  
  89. char *type2name(int t)
  90. {
  91.   static char buf[10][10];
  92.   static int bpi=0;
  93.   bpi = (bpi+1)%10;
  94.   char *bp = buf[bpi];
  95.   if (t & Tansi) *bp++ = 'A';
  96.   if (t & Tposix) *bp++ = 'P';
  97.   if (t & Tallow) *bp++ = '-';
  98.   if (t & Tother) *bp++ = '*';
  99.   if (t == 0) *bp++ = '0';
  100.   *bp = 0;
  101.   return buf[bpi];
  102. }
  103.  
  104. //-----------------------------------------------------------------------------
  105.  
  106. void figure_obj(Object *obj)
  107. {
  108.   int dt=0, rt=0;
  109.   int i;
  110.  
  111.   for (i=0; i<obj->defs.count; i++)
  112.     dt |= name2type(obj->defs[i]);
  113.   for (i=0; i<obj->refs.count; i++)
  114.     rt |= name2type(obj->refs[i]);
  115.   obj->df = dt;
  116.   obj->rf = rt;
  117. }
  118.  
  119. void diagnose_obj(Object *obj)
  120. {
  121.   char *n = obj->name;
  122.   int i, title=1;
  123.   int dtp=0, rtp=0;
  124.  
  125.   if ((obj->df & Tansi) && (obj->rf & Tposix))
  126.   {
  127.     printf("%s: (A) -> (P)\n", n);
  128.     dtp |= Tansi; rtp |= Tposix;
  129.   }
  130.   else if ((obj->df & Tansi) && (obj->rf & Tother))
  131.   {
  132.     printf("%s: (A) -> (O)\n", n);
  133.     dtp |= Tansi; rtp |= Tother;
  134.   }
  135.   else if ((obj->df & Tposix) && (obj->rf & Tother))
  136.   {
  137.     printf("%s: (P) -> (O)\n", n);
  138.     dtp |= Tposix; rtp |= Tother;
  139.   }
  140.   else if ((obj->df & Tposix) && (obj->df & Tother))
  141.   {
  142.     printf("%s: (P),(O)\n", n);
  143.     dtp |= Tansi|Tposix;
  144.   }
  145.   else if ((obj->df & Tansi) && (obj->df & Tother))
  146.   {
  147.     printf("%s: (A),(O)\n", n);
  148.     dtp |= Tansi|Tother;
  149.   }
  150.   else if ((obj->df & Tansi) && (obj->df & Tposix))
  151.   {
  152.     printf("%s: (A),(P)\n", n);
  153.     dtp |= Tother|Tposix;
  154.   }
  155.  
  156.   if ((obj->df & Tposix && obj->lf & Tansi)
  157.       || ((obj->df & Tother && obj->lf & (Tansi | Tposix))))
  158.   {
  159.     dtp = -1;
  160.     rtp = -1;
  161.     printf("%s: (%c) != stub (%s)\n", n, obj->df & Tposix ? 'P' : 'O', obj->defs[0]);
  162.   }
  163.  
  164.   for (i=0; i<obj->defs.count; i++)
  165.   {
  166.     int dt = name2type(obj->defs[i]);
  167.     if (dt & dtp)
  168.       printf("  T %s\n", obj->defs[i]);
  169.   }
  170.   for (i=0; i<obj->refs.count; i++)
  171.   {
  172.     int rt = name2type(obj->refs[i]);
  173.     if (rt & rtp)
  174.       printf("  U %s\n", obj->refs[i]);
  175.   }
  176.   if (dtp || rtp)
  177.     printf("\n");
  178.  
  179. }
  180.  
  181. //-----------------------------------------------------------------------------
  182.  
  183. void link_obj(Object *o)
  184. {
  185.   Object *o2;
  186.   int i, u, n=1;
  187.   for (i=0; i<o->refs.count; i++)
  188.   {
  189.     u = 1;
  190.     for (o2=Object::first; o2; o2=o2->next)
  191.       if (o2->defs.has(o->refs[i]))
  192.       {
  193.     u = 0;
  194.     o->deps.add(o2);
  195.     if (o2->lf & Tstub)
  196.       printf("Impure stub %s(%s) -> %s\n", o->name, o->refs[i], o2->name);
  197.     break;
  198.       }
  199.     if (u)
  200.     {
  201.       if (o->lf & Tstub)
  202.     printf("Unsettled stub %s (%s)\n", o->name, o->refs[i]);
  203.       else
  204.       {
  205.     if (n)
  206.     {
  207.       printf("Undefined symbols from %s:\n", o->name);
  208.       n = 0;
  209.     }
  210.     printf("  U %s\n", o->refs[i]);
  211.       }
  212.     }
  213.   }
  214.   if (!n)
  215.     printf("\n");
  216. }
  217.  
  218. void propogate_obj(Object *o, int Plf=0)
  219. {
  220.   static int indent=1;
  221.   int newlf;
  222.  
  223.   newlf = (o->lf | Plf | o->df) & ~Tstub;
  224.   if (o->lf == newlf)
  225.     return; /* got them all */
  226.   indent++;
  227.   o->lf = newlf;
  228.  
  229.   for (int i=0; i<o->deps.count; i++)
  230.   {
  231.     Object *o2 = o->deps.objs[i];
  232.     newlf = (o->lf | o2->df | o2->lf) & ~Tstub;
  233.     if (o2->lf != newlf)
  234.     {
  235.       propogate_obj(o2, newlf);
  236.     }
  237.   }
  238.   indent--;
  239. }
  240.  
  241. //-----------------------------------------------------------------------------
  242.  
  243. void do_missing(char *which, char **fns, StringList &all_defs)
  244. {
  245.   int n = 1;
  246.   int w = 0;
  247.   int i;
  248.  
  249.   for (i=0; fns[i]; i++)
  250.   {
  251. #if 0
  252.     if (fns == posix_fns
  253.     && (strncmp(fns[i], "tc", 2)==0
  254.         || strncmp(fns[i], "cf", 2)==0
  255.         || strncmp(fns[i], "sig", 2)==0))
  256.       continue;
  257. #endif
  258.     if (!all_defs.has(fns[i]))
  259.     {
  260.       if (n)
  261.       {
  262.     n = 0;
  263.     printf("Missing %s functions:\n", which);
  264.       }
  265.       int s = strlen(fns[i]);
  266.       if (w+s > 76)
  267.       {
  268.     putchar('\n');
  269.     w = 0;
  270.       }
  271.       printf("%s ", fns[i]);
  272.       w += s+1;
  273.     }
  274.   }
  275.   if (!n)
  276.     printf("\n\n");
  277. }
  278.  
  279. //-----------------------------------------------------------------------------
  280.  
  281. main()
  282. {
  283.   char line[1000];
  284.   char sym[1000];
  285.   Object *obj = new Object("");
  286.   int is_stub;
  287.  
  288.   StringList all_defs, all_refs, weak_defs;
  289.  
  290.   for (int i=0; predefs[i]; i++)
  291.   {
  292.     obj->defs.add(predefs[i]);
  293.     all_defs.add(predefs[i]);
  294.   }
  295.   obj = 0;
  296.  
  297.   while (fgets(line, 1000, stdin))
  298.   {
  299.     line[strlen(line)-1] = 0;
  300.     if (line[0] == 0)
  301.       continue;
  302.     if (strcmp(line+strlen(line)-3, ".o:") == 0)
  303.     {
  304.       if (obj)
  305.     figure_obj(obj);
  306.       line[strlen(line)-1] = 0;
  307.       obj = new Object(line);
  308.       is_stub = (strncmp(line, "stub", 4) == 0 && isdigit(line[4]));
  309.       if (is_stub)
  310.     obj->lf |= Tstub;
  311.     }
  312.     else if (line[8] == ' ' && isupper(line[9]) && line[10] == ' ' && line[11] == '_')
  313.     {
  314.       if (line[9] == 'U')
  315.       {
  316.     all_refs.add(line+12);
  317.     obj->refs.add(line+12);
  318.       }
  319.       else if (line[9] == 'C')
  320.       {
  321.     weak_defs.add(line+12);
  322.     obj->defs.add(line+12);
  323.       }
  324.       else
  325.       {
  326.     if (all_defs.has(line+12))
  327.       printf("Multiply defined symbol: %s in %s\n", line+12, obj->name);
  328.     all_defs.add(line+12);
  329.     obj->defs.add(line+12);
  330.       }
  331.     }
  332.   }
  333.   if (obj)
  334.     figure_obj(obj);
  335.  
  336.   for (i=0; i<weak_defs.count; i++)
  337.     all_defs.add(weak_defs[i]);
  338.  
  339.   for (obj=Object::first; obj; obj=obj->next)
  340.     link_obj(obj);
  341.   for (obj=Object::first; obj; obj=obj->next)
  342.     propogate_obj(obj);
  343.   for (obj=Object::first; obj; obj=obj->next)
  344.     diagnose_obj(obj);
  345.  
  346.   do_missing("ANSI", ansi_fns, all_defs);
  347.   do_missing("POSIX", posix_fns, all_defs);
  348.  
  349.   return 0;
  350. }
  351.